package com.zt.ztzx.service.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.captcha.generator.RandomGenerator;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zt.ztzx.model.dto.system.SysUserDto;
import com.zt.ztzx.model.entity.system.SysRoleUser;
import com.zt.ztzx.model.vo.system.LoginVo;
import com.zt.ztzx.exception.ZhentaoException;
import com.zt.ztzx.mapper.SysUserMapper;
import com.zt.ztzx.model.dto.system.LoginDto;
import com.zt.ztzx.model.entity.system.SysUser;
import com.zt.ztzx.model.vo.common.Result;
import com.zt.ztzx.model.vo.common.ResultCodeEnum;
import com.zt.ztzx.service.SysUserService;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @Author: 天山一剑卓不凡
 */
@Service
public class SysUserServiceImpl implements SysUserService {
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    /**
     * 登录流程
     * 1、数据校验
     * 2、数据库校验
     * 3、生成token保存到redis
     * 4、结果返回
     * @param loginDto
     * @return
     */
//    @SneakyThrows
    @Override
    public Result<LoginVo> login(LoginDto loginDto)  {
        //进行统一异常处理 ，自定义异常
        if (ObjectUtil.isEmpty(loginDto)){
//            throw  new RuntimeException("数据有误");
            throw new ZhentaoException(ResultCodeEnum.DATA_ERROR.getCode(),ResultCodeEnum.DATA_ERROR,ResultCodeEnum.DATA_ERROR.getMessage());
        }
        SysUser sysUser = sysUserMapper.login(loginDto.getUserName());
        //校验免密码
        String password = DigestUtils.md5DigestAsHex(loginDto.getPassword().getBytes());
        if (!StrUtil.equals(password,sysUser.getPassword())){
//            throw  new RuntimeException("密码错误");
            throw  new ZhentaoException(ResultCodeEnum.LOGIN_ERROR.getCode(),ResultCodeEnum.LOGIN_ERROR,ResultCodeEnum.LOGIN_ERROR.getMessage());
        }
        String string = redisTemplate.opsForValue().get("captcha");
        if (!StrUtil.equals(loginDto.getCodeKey(),string)){
            return Result.build(null,400,"验证码不正确，请重新输入");
        }
        //生成token
        String token = IdUtil.simpleUUID();
        //保存到redis中
        redisTemplate.opsForValue().set("user:login:"+token, JSON.toJSONString(sysUser),30, TimeUnit.MINUTES);
        LoginVo loginVo = new LoginVo();
        loginVo.setToken(token);
        loginVo.setRefresh_token("fgga");

        return Result.build(loginVo,200,"登录成功");
    }

    @Override
    public Result<SysUser> getUserinfo(String token) {
        //从redis中获取用户信息
        String str = redisTemplate.opsForValue().get("user:login:" + token);
        SysUser sysUser = JSON.parseObject(str, SysUser.class);
        return Result.build(sysUser,200,"获取用户信息成功");
    }

    /**
     * 退出登录,把token从redis中删除
     * @param token
     */
    @Override
    public void logout(String token) {
        redisTemplate.delete("user:login:"+token);

    }

    @Override

    public Result<PageInfo<SysUser>> list(SysUserDto userDto, Integer pageNum, Integer pageSize) {
        if(StringUtils.checkValNull(pageNum) || StringUtils.checkValNull(pageSize)){
            return Result.build(null,400,"参数不能为空");
        }
        PageHelper.startPage(pageNum,pageSize);
        List<SysUser> list =  sysUserMapper.selectUserList(userDto);
        PageInfo<SysUser> pageInfo = new PageInfo<>(list);
        return Result.build(pageInfo,200,"查询成功");
    }

    /**
     * 添加用户
     * @param sysUser
     * @return
     */
    @Override
    public Result saveUser(SysUser sysUser) {
        //参数校验
        if(Objects.isNull(sysUser)){
            return Result.build(null,400,"用户参数不能为空");
        }

        String password = DigestUtils.md5DigestAsHex(sysUser.getPassword().getBytes());
        sysUser.setPassword(password);
        sysUser.setCreateTime(new DateTime());
        sysUser.setUpdateTime(new DateTime());
        int i = sysUserMapper.saveUser(sysUser);
        return Result.build(i,200,"添加成功");
    }

    /**
     * 根据用户ID查询他的角色
     * @param userId
     * @return
     */
    @Override
    public Result<List<Integer>> getRolesByUserId(Integer userId) {
        if(Objects.isNull(userId)){
            return Result.build(null,400,"用户ID不能为空");
        }
        List<Integer> list = sysUserMapper.getRolesByUserId(userId);
        return Result.build(list,200,"查询成功");
    }

    @Override
    public Result captcha(HttpServletResponse response) {
        // 自定义纯数字的验证码（随机4位数字，可重复）
        RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4);
        // 定义图片的显示大小
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(100, 30);
        response.setContentType("image/jpeg");
        response.setHeader("Pragma", "No-cache");

        try {
            // 调用父类的 setGenerator() 方法，设置验证码的类型
            lineCaptcha.setGenerator(randomGenerator);
            // 输出到页面
            lineCaptcha.write(response.getOutputStream());
            // 打印日志
            System.out.println("生成的验证码:{}"+lineCaptcha.getCode());
            redisTemplate.opsForValue().set("captcha",lineCaptcha.getCode(),60, TimeUnit.SECONDS);
            // 关闭流
            response.getOutputStream().close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return Result.build("发送成功",200,lineCaptcha.getCode());
    }


}
